package com.sigmatrix.h5.service.impl;

import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.RandomStringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.sigmatrix.h5.components.FeignManager;
import com.sigmatrix.h5.dao.DisDealerAcctDao;
import com.sigmatrix.h5.dao.DisDealerDao;
import com.sigmatrix.h5.dao.EnterpriseDao;
import com.sigmatrix.h5.dto.LoginData;
import com.sigmatrix.h5.entity.AdminArea;
import com.sigmatrix.h5.entity.DisDealer;
import com.sigmatrix.h5.entity.DisDealerAcct;
import com.sigmatrix.h5.entity.DisDealerAcctRegAudit;
import com.sigmatrix.h5.entity.Enterprise;
import com.sigmatrix.h5.entity.SalesArea;
import com.sigmatrix.h5.enums.CoordType;
import com.sigmatrix.h5.enums.PromotionCodeType;
import com.sigmatrix.h5.enums.RegionType;
import com.sigmatrix.h5.enums.ResponseEnum;
import com.sigmatrix.h5.enums.SynStatus;
import com.sigmatrix.h5.exception.MessageException;
import com.sigmatrix.h5.exception.ServiceException;
import com.sigmatrix.h5.feign.args.SynDealer;
import com.sigmatrix.h5.feign.mode.Franchiser;
import com.sigmatrix.h5.feign.mode.FranchiserResponse;
import com.sigmatrix.h5.response.Response;
import com.sigmatrix.h5.service.AdminAreaService;
import com.sigmatrix.h5.service.DisDealerAcctService;
import com.sigmatrix.h5.service.DisDealerService;
import com.sigmatrix.h5.service.EnterpriseService;
import com.sigmatrix.h5.service.SalesAreaService;
import com.sigmatrix.h5.utils.Assert;
import com.sigmatrix.h5.utils.CommonUtils;
import com.sigmatrix.h5.utils.Cons;
import com.sigmatrix.h5.utils.Constants;
import com.sigmatrix.h5.utils.MD5Utils;
import com.sigmatrix.h5.utils.SessionUtils;
import com.sigmatrix.h5.utils.Utils;
import com.sigmatrix.h5.utils.baidu.BaiduMapUtils;
import com.sigmatrix.h5.utils.baidu.po.AddressComponent;
import com.sigmatrix.h5.utils.baidu.po.LatLngLocation;
import com.sigmatrix.h5.web.args.DealerRegParam;
import com.sigmatrix.h5.web.vo.LoginVo;
import com.sigmatrix.sc.jdbc.common.service.ServiceImpl;

/**
 * 
 *@ClassName: DistributionDealersServiceImpl
 *@Description: 经销商表
 *@author MH
 *@date 2017年9月27日 上午11:01:57
 */
@Service
public class DisDealerServiceImpl extends ServiceImpl<DisDealer, Integer> implements DisDealerService{
	
	@Autowired
	private DisDealerDao disDealerDao;

	@Autowired
	private DisDealerAcctDao disDealerAcctDao;
	
	@Autowired
	private EnterpriseService enterpriseService;
	
	@Autowired
	private FeignManager feignManager;
	
	@Autowired
	private AdminAreaService adminAreaService;
	
	@Autowired
	private SalesAreaService salesAreaService;
	
	@Autowired
	private DisDealerAcctService disDealerAccrService;
	
	@Autowired
	private transient EnterpriseDao enterpriseDao;
	
	@Override
	public DisDealer findFirstLevelParent(Integer id) {
		return disDealerDao.findFirstLevelParent(id);
	}

	@Override
	public List<DisDealer> findParents(String dealerCode) {
		return disDealerDao.findParents(dealerCode);
	}
	@Override
	public List<DisDealer> findParents(Integer id) {
		return disDealerDao.findParents(id);
	}
	@Override
	public List<DisDealer> findByIds(Object... ids) {
		return disDealerDao.findByIds(ids);
	}
	@Override
	public Integer saveTempRecord(DealerRegParam registInfo) {
		//校验参数是否合法
		assertArgsLegal(registInfo);
		DisDealer dealer = new DisDealer();
		//联系电话、营业执照、经销商名称、省份、城市、经度、纬度、详细地址
		BeanUtils.copyProperties(registInfo, dealer);
		//设置特殊属性
		dealer.setPromotionCode(null);
		dealer.setContact(registInfo.getContactUserName());//联系人姓名
		dealer.setBasicModuleEnterpriseId(SessionUtils.getbasicMoudleEseId());//企业基础数据ID
		dealer.setEnterpriseId(SessionUtils.getEseId());//企业ID
		PromotionCodeType type = assembleParent(registInfo.getPromotionCode(), dealer);//设置父级经销商
		dealer.setStatus(Constants.STATUS_DISABLE);//默认状态为禁用，审批通过以后再启用
		dealer.setCreateTime(new Date());
		registInfo.setPromotionCodeType(type.value);
		return insertSelective(dealer);
	}
	
	/**
	 * 
	 *@Title: assertArgsLegal
	 *@Description: 校验参数是否合法
	 *@return void
	 *@author MH
	 *@date 2017年11月8日 下午1:56:49
	 *@param registInfo
	 */
	private void assertArgsLegal(DealerRegParam registInfo){
		//检查手机号跟名称的唯一性
		int i = disDealerDao.selectCountByDealerName(registInfo.getName());
		if(i > 0) throw new MessageException("经销商名称已经存在");
		i = disDealerAcctDao.selectCountByAccount(registInfo.getCellPhoneNum());
		if(i > 0)throw new MessageException("该手机号已经注册过");
	}
	
	/**
	 * 
	 *@Title: assembleParent
	 *@Description: 组装上级经销商
	 *@return void
	 *@author MH
	 *@date 2017年11月8日 下午3:11:01
	 *@param promotionCode
	 *@param dealer
	 */
	private PromotionCodeType assembleParent(String promotionCode,DisDealer dealer){
		DisDealer parent = disDealerDao.findByPromotionCode(promotionCode);
		PromotionCodeType  type = PromotionCodeType.DEALER;
		if(CommonUtils.isEmpty(parent)){
			DisDealerAcct acct = disDealerAccrService.findByPromotionCode(promotionCode);
			Assert.notNull(acct, "推广码错误");
			Assert.notNull(acct.getDealerId(), "无效的推广码，请重新核对");
			parent = findById(acct.getDealerId());
			type = PromotionCodeType.SALES_MAN;
		}
		dealer.setParentId(parent.getId());
		dealer.setBasicModuleParentId(parent.getBasicModuleId());
		Short level = parent.getLevel() == null ?0:parent.getLevel();
		dealer.setLevel(++level);
		dealer.setSalesRegion(parent.getSalesRegion());
		dealer.setRegionType(parent.getRegionType());
		return type;
	}

	@Override
	public boolean validateOpenId(String openId) {
		DisDealer dealer = new DisDealer();
		dealer.setOpenId(openId);
		int i = disDealerDao.selectCount(dealer);
		if(i > 0) return true;
		return false;
	}

	@Override
	public DisDealer synDealer(DisDealerAcctRegAudit audit,DisDealer dealer) {
		SynDealer syn = initSynDealer(audit,dealer);
		setParentInfo(syn, dealer.getParentId());
		setEnterpriseInfo(syn, dealer.getEnterpriseId());
		syn(syn,dealer);//基础数据同步
		dealer.setStatus(Constants.STATUS_ENABLE);
		dealer.setUpdateTime(new Date());
		updateSelective(dealer);
		return dealer;
	}
	
	/**
	 * 
	 *@Title: initSynDealer
	 *@Description: 初始化同步参数
	 *@return SynDealer
	 *@author MH
	 *@date 2017年11月10日 下午6:54:09
	 *@param audit
	 *@return
	 */
	private SynDealer initSynDealer(DisDealerAcctRegAudit audit,DisDealer dealer){
		Assert.notNull(dealer.getName(), "经销商名称为空");
		SynDealer syn = new SynDealer();
		syn.setCityCode(dealer.getCity());
		syn.setProvinceCode(dealer.getProvince());
		syn.setContacts(dealer.getContact());
		if(CommonUtils.isNumber(dealer.getLat()))syn.setLat(Float.valueOf(dealer.getLat()));
		if(CommonUtils.isNumber(dealer.getLng()))syn.setLng(Float.valueOf(dealer.getLng()));
		syn.setLevel(dealer.getLevel()*1);
		syn.setLicenceNo(dealer.getLicenseCode());
		syn.setName(dealer.getName());
		syn.setPhone(dealer.getCellPhoneNum());
		syn.setRemark(dealer.getRemarks());
		return syn;
	}
	
	private void setEnterpriseInfo(SynDealer syn,Integer enterpriseId){
		Enterprise enterprise = enterpriseService.findById(enterpriseId);
		Assert.notNull(enterprise, "没有查询到企业");
		syn.setEseId(Long.valueOf(enterprise.getBasicModuleId()));
	}
	
	private void setParentInfo(SynDealer syn,Integer parentId){
		DisDealer parent = findById(parentId);
		Assert.notNull(parent, "没有查询到上级经销商");
		syn.setParentId(Long.valueOf(parent.getBasicModuleId()));
		syn.setCode(RandomStringUtils.random(10, "0123456789"));
	}
	
	private void syn(SynDealer syn,DisDealer dealer){
		FranchiserResponse response = feignManager.registDealer(syn);
		while(CommonUtils.isEmpty(response.getData())){
			//如果是编码重复就重新生成编码继续同步
			if(SynStatus.CODE_ERROR.code.equals(response.getCode())){
				syn.setCode(RandomStringUtils.random(10, "0123456789"));
				response = feignManager.registDealer(syn);
			}else{
				throw new MessageException(response.getMessage());
			}
		}
		Franchiser fan = null;
		Assert.notNull((fan = response.getData()), "基础数据返回的信息为空");
		Assert.notNull(fan.getPromoCode(), "基础数据同步返回的推广码为空");
		Assert.notNull(fan.getId(), "基础数据同步返回的ID为空");
		dealer.setBasicModuleId(fan.getId());
		dealer.setPromotionCode(fan.getPromoCode()+"");
		dealer.setCode(fan.getCode());
	}
	
	@Override
	public List<DisDealer> findChildren(Integer id) {
		return disDealerDao.findChildren(id);
	}
	@Override
	public DisDealer getDealerInfo(Integer dealerId) {
		DisDealer dealer = findById(dealerId);
		List<AdminArea> areas = adminAreaService.findByIds(dealer.getProvince(),dealer.getCity(),dealer.getCitySubOrdinate());
		StringBuffer sb = new StringBuffer();
		if(CommonUtils.isNotEmpty(areas)){
			Collections.sort(areas, (f,a) -> f.getType()-a.getType());
			areas.forEach(x ->{sb.append(x.getName());});
			dealer.setAddress(sb.toString());
		}
		return dealer;
	}
	
	@Override
	public boolean checkFleeing(Integer dealerId, String lat, String lng) {
		Assert.notNull(lat, lng, "经纬度不能为空");
		LatLngLocation location = BaiduMapUtils.parseLatAndLng(lat, lng,CoordType.GCJ02LL);
		Assert.notNull(location, "GPS定位失败");
		return checkFleeing(dealerId, location);
	}
	@Override
	public boolean checkFleeing(Integer dealerId, LatLngLocation location) {
		//解析行政区域
		Map<String, String> salesAreas = analysisArea(dealerId);
		List<AdminArea> areas = adminAreaService.findByAllByCache();
		for (AdminArea adminArea : areas) {
			AddressComponent address = location.getResult().getAddressComponent();
			if(adminArea.getName().contains(address.getProvince()) ||
					adminArea.getName().contains(address.getCity()) || 
					adminArea.getName().contains(address.getDistrict())){
				if(salesAreas.containsKey(adminArea.getId()+"")){
					return true;
				}
			}
		}
		return false;
	}
	public Map<String,String> analysisArea(Integer dealerId){
		Map<String,String> map = new HashMap<>();
		DisDealer dealer = findById(dealerId);
		Assert.notNull(dealer, "经销商ID错误");
		Assert.notNull(dealer.getSalesRegion(), String.format("经销商[%s]没有销售区域", dealer.getId()));
		String[] _array = dealer.getSalesRegion().split(",");
		//销售区域
		if(RegionType.SALES_AREA.value.equals(dealer.getRegionType())){
			List<SalesArea> salesAreas = salesAreaService.findByIds(_array);
			Assert.notNull(salesAreas, String.format("经销商[%s]销售区域异常", dealer.getId()));
			salesAreas.stream().flatMap(x -> {
				Assert.notNull(x.getZoneCodes(), String.format("销售区域[%s]没有行政区域", x.getId()));
				return Arrays.stream(x.getZoneCodes().split(","));
				})
			.forEach(x -> map.put(x, null));
		}else{
			//行政区域
			for (int i = 0; i < _array.length; i++) {
				map.put(_array[i], null);
			}
		}
		
		return map;
	}

	@Override
	public List<DisDealer> findParentsByPromotionCode(String promotionCode) {
		return disDealerDao.findParentsByPromotionCode(promotionCode);
	}

	@Override
	public DisDealer findByPromotionCode(String promotionCode) {
		return disDealerDao.findByPromotionCode(promotionCode);
	}
	
	/**
	 * 分销app合并分支开始-------------------------------------
	 */
	 
	
	/**(non-Javadoc)
	 *@Title: validateLogin
	 *@Description: 
	 *@see com.sigmatrix.h5.service.DisDealersAcctService#validateLogin(com.sigmatrix.h5.web.vo.LoginVo)
	 *@date 2017年8月15日 上午12:13:19
	 */
	public Response validateLogin(LoginVo vo) throws ServiceException {
		//根据账号查询
		try {
			final DisDealerAcct dealerAcct = disDealerAcctDao.findByAcct(null, vo.getAccount());
			if(Utils.isEmpty(dealerAcct)){
				return new Response(ResponseEnum.NO_DATA,dealerAcct);
			}
			//判断状态是否为启用
			if(Cons.STATUS_ENABLE != dealerAcct.getStatus()){
				return new Response(ResponseEnum.EXCEPTION.getCode(),"账号不可用");
			}
		    //账号类型, 1-企业CRM账号,2-经销商CRM账号,3-终端门店CRM账号
			if(Cons.ACCT_TYPE_DEALER != dealerAcct.getAcctType()){
				return new Response(ResponseEnum.EXCEPTION.getCode(),"请使用经销商CRM账号");
			}
			//密码加密验证是否正确
			final String pwd = MD5Utils.getMD5Code(vo.getPwd());
			if(!pwd.equals(dealerAcct.getPwd())){
				return new Response(ResponseEnum.EXCEPTION.getCode(),"密码不正确");
			}
			
			//查询账号所属企业信息
			Enterprise enterprise = null;//企业信息
			final Integer eseId = dealerAcct.getEnterpriseId();//企业id
			if(Utils.isNotEmpty(eseId)){
				enterprise = enterpriseDao.findById(eseId);
			}
			if(Utils.isEmpty(enterprise)||Utils.isEmpty(enterprise.getCode())){
				return new Response(ResponseEnum.EXCEPTION.getCode(),"账号企业信息不存在");
			}
			//登录返回信息
			final LoginData loginData = new LoginData();
			loginData.setEnterpriseCode(enterprise.getCode());//企业code
			loginData.setUserDealerId(dealerAcct.getDealerId());//经销商id
			loginData.setUserId(dealerAcct.getId());//经销商账号id
			return new Response(ResponseEnum.SUCCESS, loginData);
		} catch (Exception e) {
			throw new ServiceException(e);
		}
	}
	
	
	/**
	 * 分销app合并分支结束-------------------------------------
	 */
	 

}
